using Digitalmes.Domain.Entities.Mes.Masters;

namespace Digitalmes.Application.Mes.Masters.Materials.Commands;

/// <summary>
/// 更新物料命令。
/// </summary>
public record UpdateMaterialCommand(long Id, MdMaterialDto Material) : IRequest<IResult<bool>>;

internal sealed class UpdateMaterialCommandHandler(IRepository<MdMaterial> repo) : IRequestHandler<UpdateMaterialCommand, IResult<bool>>
{
    public async Task<IResult<bool>> Handle(UpdateMaterialCommand request, CancellationToken cancellationToken)
    {
        // 检查编号是否已存在。
        if (await repo.IsAnyAsync(m => m.Code == request.Material.Code && m.Id != request.Id, cancellationToken))
        {
            return Result.Failure("物料编号已存在");
        }

        var material = await repo.GetByIdAsync(request.Id, cancellationToken);
        if (material == null)
        {
            return Result.Failure("未找到要更新的物料");
        }

        // 确保规则项不为 null，可以为空集合。
        var rules = request.Material.Rules;
        rules?.RemoveAll(string.IsNullOrWhiteSpace);

        material.Name = request.Material.Name;
        material.Type = request.Material.Type;
        material.Attr = request.Material.Attr;
        material.Model = request.Material.Model;
        material.Spec = request.Material.Spec;
        material.Unit = request.Material.Unit;
        material.Rules = rules ?? [];
        material.Supplier = request.Material.Supplier;
        material.ManufacturingDate = request.Material.ManufacturingDate;
        material.WarehousingDate = request.Material.WarehousingDate;
        material.Remark = request.Material.Remark;
        material.Status = request.Material.Status;

        var ok = await repo.UpdateAsync(material, m => new
        {
            m.Name,
            m.Type,
            m.Attr,
            m.Model,
            m.Spec,
            m.Unit,
            m.Rules,
            m.Supplier,
            m.ManufacturingDate,
            m.WarehousingDate,
            m.Remark,
            m.Status,
            m.UpdatedBy,
            m.UpdatedTime,
        }, cancellationToken);
        return Result.From(ok);
    }
}
